<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>demo</title>
    <script src="https://cdn.bootcdn.net/ajax/libs/d3/7.8.5/d3.min.js"></script>
  </head>
  <body>
    <div class="container">
      <svg id="chart"></svg>
    </div>

    <script>
      const chart = d3.select("#chart").attr("width", 500).attr("height", 200);

      const heightOf = d3.scaleLinear().domain([0, 40]).range([0, 200]);

      const yOf = d3.scaleLinear().domain([0, 40]).range([200, 0]);

      const data = [10, 20, 30, 35];
      const bW = 20;

      // join( EnterSet, ExitSet ) = UpdateSet

      function update(data) {
        const bars = chart.selectAll("g").data(data);

        bars
          .select("text")
          .attr("y", (d) => {
            return yOf(d) + 10;
          })
          .attr("x", bW / 2 - 5)
          .attr("fill", "white")
          .text((d) => d + "");

        bars.select("rect").attr("y", yOf).attr("height", heightOf);

        const enterList = bars
          .enter()
          .append("g")
          .attr("transform", (d, i) => {
            return `translate(${bW * i}, 0)`;
          });

        enterList
          .append("rect")
          .attr("width", bW - 1)
          .attr("height", heightOf)
          .attr("y", 200)
          .transition()
          .attr("y", yOf)
          .attr("fill", "steelblue");

        enterList
          .append("text")
          .attr("y", (d) => {
            return yOf(d) + 10;
          })
          .attr("x", bW / 2 - 5)
          .attr("fill", "white")
          .text((d) => d + "");

        const exitList = bars
          .exit()
          .selectAll("rect")
          .transition()
          .attr("y", 200);
        // .on('end', () => {
        // 	bars.exit().remove()
        // })
      }

      setInterval(() => {
        if (Math.random() > 0.5) {
          data.push(10 + Math.floor(Math.random() * 30));
        } else {
          data.pop();
        }
        update(data);
      }, 3000);

      update(data);
    </script>
  </body>
</html>
